package com.pai4j.ugc.repository.dao;
import com.pai4j.ugc.repository.entity.ChatMessageEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.Date;
import java.util.List;


@Repository
public interface IChatMessageDAO extends JpaSpecificationExecutor<ChatMessageEntity>, JpaRepository<ChatMessageEntity, Long> {

    @Query(value = "select distinct mess from ChatMessageEntity mess where "
            + "(mess.sender = :sender or mess.receiver = :receiver) and "
            + "(mess.receiver = :sender or mess.sender = :receiver) order by mess.id desc")
    List<ChatMessageEntity> findAllBySenderAndReceiver(String sender, String receiver);

    Page<ChatMessageEntity> findAllByMessageLike(String message, Pageable pageable);


    @Query(value = "select mess from ChatMessageEntity mess " +
                    "where ((mess.sender = :sourceUserId and mess.receiver = :targetUserId) or " +
                    "(mess.sender = :targetUserId and mess.receiver = :sourceUserId)) " +
                    "and mess.sendDate between :startDate and :endDate")
    Page<ChatMessageEntity> findAllBySenderAndReceiverAndSendDateBefore(String sourceUserId,
                                                                        String targetUserId,
                                                                        Date startDate,
                                                                        Date endDate,
                                                                        Pageable pageable
                                                                        );

    /**
     * 查询两个用户之间的聊天记录，支持按ID范围查询
     * 用于缓存失效时从数据库加载数据
     *
     * @param sender 发送人
     * @param receiver 接收人
     * @param maxId 最大消息ID（不包含），传null或Long.MAX_VALUE表示查询最新的消息
     * @param pageable 分页参数
     * @return 消息列表
     */
    @Query(value = "select mess from ChatMessageEntity mess " +
                    "where ((mess.sender = :sender and mess.receiver = :receiver) or " +
                    "(mess.sender = :receiver and mess.receiver = :sender)) " +
                    "and mess.id < :maxId " +
                    "order by mess.id desc")
    List<ChatMessageEntity> findChatMessagesByIdRange(String sender, 
                                                       String receiver, 
                                                       Long maxId, 
                                                       Pageable pageable);

    /**
     * 根据消息唯一标识查询消息（用于幂等性检查）
     *
     * @param messageUuid 消息唯一标识
     * @return 消息实体
     */
    ChatMessageEntity findByMessageUuid(String messageUuid);

    /**
     * 检查消息是否已存在（用于幂等性检查）
     *
     * @param messageUuid 消息唯一标识
     * @return 是否存在
     */
    boolean existsByMessageUuid(String messageUuid);

    /**
     * 批量更新两个用户之间的未读消息为已读状态
     * 用于用户查看消息时标记已读
     *
     * @param receiver 消息接收人（当前用户）
     * @param sender 消息发送人（聊天对象）
     * @return 更新的记录数
     */
    @Query(value = "update ChatMessageEntity mess set mess.isRead = true " +
                    "where mess.receiver = :receiver and mess.sender = :sender and mess.isRead = false")
    @org.springframework.data.jpa.repository.Modifying
    @org.springframework.transaction.annotation.Transactional
    int markMessagesAsReadBySenderAndReceiver(String receiver, String sender);

    /**
     * 查询两个用户之间的未读消息数量
     *
     * @param receiver 消息接收人（当前用户）
     * @param sender 消息发送人（聊天对象）
     * @return 未读消息数量
     */
    @Query(value = "select count(mess) from ChatMessageEntity mess " +
                    "where mess.receiver = :receiver and mess.sender = :sender and mess.isRead = false")
    long countUnreadMessages(String receiver, String sender);
}